﻿using System;
using System.Globalization;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Printing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using MPMovieCatalog.Service;
using MPMovieCatalog.Domain;
using MPMovieCatalog.Util;
using MPMovieCatalog.Configuration;
using MPMovieCatalog.Configuration.Sections;

namespace MPMovieCatalog.Forms
{
    public partial class PrintForm : Form
    {
        private WebBrowserDocumentCompletedEventHandler m_previewHandler;

        private WebBrowserDocumentCompletedEventHandler m_printHandler;

        private Dictionary<string, FontFamily> families = new Dictionary<string, FontFamily>();

        public PrintForm()
        {
            InitializeComponent();

            m_previewHandler = new WebBrowserDocumentCompletedEventHandler(Preview);
            m_printHandler = new WebBrowserDocumentCompletedEventHandler(Print);

            UpdateUI();
        }

        public ArrayList SelectedMovies { get; set; }

        public long AllMoviesCount { get; set; }

        private void PrintForm_Load(object sender, EventArgs e)
        {
            foreach (FontFamily fontFamily in FontFamily.Families)
            {
                fontComboBox.Items.Add(fontFamily.Name);
                families[fontFamily.Name] = fontFamily;
            }

            templateComboBox.DataSource = TemplateUtils.FindAllTemplates(TemplateType.Print, true);

            ConfigurationWrapper wrapper = new ConfigurationWrapper();
            reportTitleTextBox.Text = wrapper.PrintSection.Title;
            fontComboBox.SelectedItem = wrapper.PrintSection.FontName;
            fontSizeUpDown.Value = wrapper.PrintSection.FontSize;
            fontColorPanel.BackColor = ColorTranslator.FromHtml(wrapper.PrintSection.FontColor);
            shadingCheckBox.Checked = wrapper.PrintSection.ShadingEnabled;
            thumbCheckBox.Checked = wrapper.PrintSection.ShowThumb;

            allMoviesRadioButton.Text = string.Format(ResourceUtils.GetString("print", 2), AllMoviesCount);
            selectedMoviesRadioButton.Text = string.Format(ResourceUtils.GetString("print", 3), SelectedMovies == null ? 0 : SelectedMovies.Count);
        }

        private void previewButton_Click(object sender, EventArgs e)
        {
            GeneratePrint(m_previewHandler);
        }

        private void printButton_Click(object sender, EventArgs e)
        {
            GeneratePrint(m_printHandler);
        }

        private void GeneratePrint(WebBrowserDocumentCompletedEventHandler handler)
        {
            webBrowser.DocumentCompleted -= m_previewHandler;
            webBrowser.DocumentCompleted -= m_printHandler;
            webBrowser.DocumentCompleted += handler;

            ArrayList ids = null;
            if (selectedMoviesRadioButton.Checked)
            {
                ids = new ArrayList();
                if (SelectedMovies != null && SelectedMovies.Count > 0)
                {
                    foreach (MovieShortInfo movieShortInfo in SelectedMovies)
                    {
                        ids.Add(movieShortInfo.Id);
                    }
                }
                else
                {
                    ids.Add(0);
                }
            }
            ArrayList movies = MovieServiceFactory.getMovieService().FindMovieInfoByIds(ids);

            if (customizeTemplateRadioButton.Checked)
            {
                ConfigurationWrapper wrapper = new ConfigurationWrapper();
                webBrowser.DocumentText = TemplateUtils.TransformMovies(movies, wrapper.PrintSection.Fields, reportTitleTextBox.Text, fontComboBox.SelectedItem.ToString(), fontSizeUpDown.Value, ColorTranslator.ToHtml(fontColorPanel.BackColor), shadingCheckBox.Checked, thumbCheckBox.Checked);
            }
            else
            {
                Template template = templateComboBox.SelectedItem as Template;
                webBrowser.DocumentText = TemplateUtils.TransformMovies(movies, TemplateType.Print, template.Name, true, true, null);
            }
        }

        private void Preview(object sender, WebBrowserDocumentCompletedEventArgs args)
        {
            webBrowser.ShowPrintPreviewDialog();
        }

        private void Print(object sender, WebBrowserDocumentCompletedEventArgs args)
        {
            webBrowser.ShowPrintDialog();
        }

        private void customizeTemplateRadioButton_CheckedChanged(object sender, EventArgs e)
        {
            customizeTemplateGroupBox.Enabled = customizeTemplateRadioButton.Checked;
            templateComboBox.Enabled = !customizeTemplateRadioButton.Checked;
        }

        private void fontColorButton_Click(object sender, EventArgs e)
        {
            colorDialog.Color = fontColorPanel.BackColor;
            if (colorDialog.ShowDialog(this) == DialogResult.OK)
            {
                fontColorPanel.BackColor = colorDialog.Color;
            }
        }

        private void fontComboBox_DrawItem(object sender, DrawItemEventArgs e)
        {
            e.DrawBackground();

            if (e.Index >= 0)
            {
                System.Drawing.Font font = e.Font;

                FontFamily fontFamily = families[fontComboBox.Items[e.Index] as string];
                if (fontFamily.IsStyleAvailable(FontStyle.Regular))
                {
                    font = new Font(fontFamily, e.Font.Size);
                }
                else if (fontFamily.IsStyleAvailable(FontStyle.Bold))
                {
                    font = new Font(fontFamily, e.Font.Size, FontStyle.Bold);
                }
                else if (fontFamily.IsStyleAvailable(FontStyle.Italic))
                {
                    font = new Font(fontFamily, e.Font.Size, FontStyle.Italic);
                }

                e.Graphics.DrawString(fontFamily.Name, font, new SolidBrush(e.ForeColor), e.Bounds);
            }

            e.DrawFocusRectangle();
        }

        private void fieldsButton_Click(object sender, EventArgs e)
        {
            using (FieldsForm fieldsForm = new FieldsForm())
            {
                ConfigurationWrapper wrapper = new ConfigurationWrapper();
                fieldsForm.SelectedFields = wrapper.PrintSection.Fields;

                if (fieldsForm.ShowDialog(this) == DialogResult.OK)
                {
                    wrapper.PrintSection.Fields = fieldsForm.SelectedFields;
                    wrapper.SaveConfiguration();
                }
            }
        }

        private void PrintForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            ConfigurationWrapper wrapper = new ConfigurationWrapper();
            wrapper.PrintSection.Title = reportTitleTextBox.Text;
            wrapper.PrintSection.FontName = fontComboBox.SelectedItem as string;
            wrapper.PrintSection.FontSize = fontSizeUpDown.Value;
            wrapper.PrintSection.FontColor = ColorTranslator.ToHtml(fontColorPanel.BackColor);
            wrapper.PrintSection.ShadingEnabled = shadingCheckBox.Checked;
            wrapper.PrintSection.ShowThumb = thumbCheckBox.Checked;

            wrapper.SaveConfiguration();

        }

        private void UpdateUI()
        {
            this.Text = ResourceUtils.GetString("print", 0);
            moviesGroupBox.Text = ResourceUtils.GetString("print", 1);
            templateGroupBox.Text = ResourceUtils.GetString("print", 4);
            customizeTemplateRadioButton.Text = ResourceUtils.GetString("print", 5);
            reportTitleLabel.Text = ResourceUtils.GetString("print", 6);
            fontLabel.Text = ResourceUtils.GetString("print", 7);
            fontSizeLabel.Text = ResourceUtils.GetString("print", 8);
            fontColorLabel.Text = ResourceUtils.GetString("print", 9);
            shadingCheckBox.Text = ResourceUtils.GetString("print", 10);
            thumbCheckBox.Text = ResourceUtils.GetString("print", 11);
            fieldsButton.Text = ResourceUtils.GetString("print", 12);
            selectTemplateRadioButton.Text = ResourceUtils.GetString("print", 13);
            printButton.Text = ResourceUtils.GetString("print", 14);
            previewButton.Text = ResourceUtils.GetString("print", 15);
            closeButton.Text = ResourceUtils.GetString("print", 16);
        }

        /*
        private void previewButton_Click(object sender, EventArgs e)
        {
            AxSHDocVw.AxWebBrowser webBrowser;
            SHDocVw.IWebBrowser2 iWB = (SHDocVw.IWebBrowser2)m_webbrowser.ActiveXInstance;

            object objIn = @"D:\PrintTemplate.html";
            object objOut = null;
            iWB.ExecWB(SHDocVw.OLECMDID.OLECMDID_PRINTPREVIEW, SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT, ref objIn, ref objOut);

            moviesToPrint = MovieServiceFactory.getMovieService().FindAllMoviesShortInfo();
            moviesEnumerator = moviesToPrint.GetEnumerator();
            printFont = new Font("Arial", 10);

            PrintDocument printDocument = new PrintDocument();
            printDocument.PrintPage += new PrintPageEventHandler(printDocument_PrintPage);

            PrintPreviewDialog preview = new PrintPreviewDialog();
            preview.Document = printDocument;

            preview.ShowDialog(this);
        }

        private void printDocument_PrintPage(object sender, PrintPageEventArgs ev)
        {
            float linesPerPage = 0;
            float yPos = 0;
            int count = 0;
            float leftMargin = ev.MarginBounds.Left;
            float topMargin = ev.MarginBounds.Top;
            bool hasNext = false;

            // Calculate the number of lines per page.
            linesPerPage = ev.MarginBounds.Height /
               printFont.GetHeight(ev.Graphics);

            // Print each line of the file.
            while (count < linesPerPage && (hasNext = moviesEnumerator.MoveNext() == true))
            {
                yPos = topMargin + (count *
                   printFont.GetHeight(ev.Graphics));
                ev.Graphics.DrawString(moviesEnumerator.Current.ToString(), printFont, Brushes.Black,
                   leftMargin, yPos, new StringFormat());
                count++;
            }

            // If more lines exist, print another page.
            if (hasNext)
                ev.HasMorePages = true;
            else
                ev.HasMorePages = false;
        }
         */
    }
}
